//
// Created by francklinson on 2021/7/14 AT 0:08.
//

//给你两个正整数数组 nums1 和 nums2 ，数组的长度都是 n 。
//
//数组 nums1 和 nums2 的 绝对差值和 定义为所有 |nums1[i] - nums2[i]|（0 <= i < n）的 总和（下标从 0 开始）。
//
//你可以选用 nums1 中的 任意一个 元素来替换 nums1 中的 至多 一个元素，以 最小化 绝对差值和。
//
//在替换数组 nums1 中最多一个元素 之后 ，返回最小绝对差值和。因为答案可能很大，所以需要对 109 + 7 取余 后返回。
//
//来源：力扣（LeetCode）
//链接：https://leetcode-cn.com/problems/minimum-absolute-sum-difference
//著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

class Solution {
public:
    /**
     * 对任意第i位都可以进行替换 替换应该找到最接近nums2[i]的nums1[j]
     * @param nums1
     * @param nums2
     * @return
     */
    static constexpr int mod = 1'000'000'007;

    int minAbsoluteSumDiff(vector<int> &nums1, vector<int> &nums2) {
        vector<int> rec(nums1);
        sort(rec.begin(), rec.end());
        int sum = 0, maxN = 0;  // maxN是替换后能实现的最大缩小
        unsigned int n = nums1.size();
        for (int i = 0; i < n; ++i) {
            int diff = abs(nums1[i] - nums2[i]);
            sum = (sum + diff) % mod;
            // 对应于这一个i的最佳的j
            int j = lower_bound(rec.begin(), rec.end(), nums2[i]) - rec.begin();
            // 这个j对应的可能大 可能小
            if (j < n)
                maxN = max(maxN, diff - (rec[j] - nums2[i]));
            if (j > 0)
                maxN = max(maxN, diff - (nums2[i] - rec[j - 1]));

        }
        return (sum - maxN) % mod;
    }
};

int main() {
    vector<int> nums1{1, 10, 4, 4, 2, 7};
    vector<int> nums2{9, 3, 5, 1, 7, 4};
    Solution sol;
    cout << sol.minAbsoluteSumDiff(nums1, nums2);
    return 0;
}

